//------------------------------------------------------------------------------
//
//   author: 小兵（aosnow@yeah.net）
//   create: 2012-5-26 下午3:32:16
//    class: HttpResultFormator - HTTP请求后的结果格式化处理方法
//
//------------------------------------------------------------------------------

package starfire.rpc.http
{
	import flash.utils.ByteArray;

	import starfire.utils.strings.jsond;
	import starfire.utils.strings.trim;

	public class HttpResult
	{

		/** 返回值为：<code>a=1&b=2&c=3</code> **/
		public static const RESULT_FORMAT_FLASHVARS:String = "flashvars";

		/** 返回值为：<code>{"a":1,"b":true,"c":"it's a string"}</code> **/
		public static const RESULT_FORMAT_JSON:String = "json";

		/** 返回值为：<code>{a:1,b:true,c:"it's a string"}</code> **/
		public static const RESULT_FORMAT_OBJECT:String = "object";

		/** 返回值为：<code>"it's a string, a long string!"</code> **/
		public static const RESULT_FORMAT_TEXT:String = "text";

		/**
		 * 返回值为：<br/>
		 * <code>&lt;xml name="nodename"><br/>
		 * 	&lt;a value="1"/><br/>
		 * 	&lt;b value="2"/><br/>
		 * 	&lt;c value="3"/><br/>
		 * &lt;/xml></code>
		 */
		public static const RESULT_FORMAT_XML:String = "xml";

		/**
		 * 指示所接收的结果为二进制数据（你无法直接设置此类型，只有当提交的数据为 ByteArray 类型时，
		 * 系统才会自动将结果类型更改为二进制数据类型，介时需要用户自定义处理二进制数据方法）  **/
		public static const RESULT_FORMAT_BINARY:String = "binary";

		public function HttpResult()
		{
		}

		public static function processResult( body:Object, resultFormat:String ):*
		{
			if( resultFormat == RESULT_FORMAT_BINARY )
				return body as ByteArray;

			var result:*;

			if( body == null || ( body && body is String && ( trim( String( body )) == "" )))
			{
				result = String( body );
			}
			else if( body is String )
			{
				var strResult:String = String( body );

				if( resultFormat == RESULT_FORMAT_XML )
				{
					result = new XML( strResult );
				}
				else if( resultFormat == RESULT_FORMAT_JSON )
				{
					result = strResult && strResult != "" ? jsond( strResult, false ) : strResult;
				}
				else if( resultFormat == RESULT_FORMAT_OBJECT )
				{
					result = decodeObject( strResult );
				}
				else if( resultFormat == RESULT_FORMAT_FLASHVARS )
				{
					result = decodeParameterString( strResult );
				}
				else
				{
					result = strResult;
				}
			}
			else
			{
				result = body;
			}

			return result;
		}

		//--------------------------------------------------------------------------
		//
		// Private Methods
		// 
		//--------------------------------------------------------------------------  

		private static function decodeParameterString( source:String ):Object
		{
			var trimmed:String = trim( source );
			var params:Array = trimmed.split( '&' );
			var decoded:Object = {};

			for( var i:int = 0; i < params.length; i++ )
			{
				var param:String = params[ i ];
				var equalsIndex:int = param.indexOf( '=' );

				if( equalsIndex != -1 )
				{
					var name:String = param.substr( 0, equalsIndex );
					name = name.split( '+' ).join( ' ' );
					name = unescape( name );
					var value:String = param.substr( equalsIndex + 1 );
					value = value.split( '+' ).join( ' ' );
					value = unescape( value );
					decoded[ name ] = value;
				}
			}

			return decoded;
		}

		private static function decodeObject( source:String, sourceA:Array = null ):Object
		{
			var obj:Object = {};
			var sa:Array;

			var separator:int;
			var key:String;
			var value:String;

			if( sourceA )
			{
				sa = sourceA;
			}
			else
			{
				source = source.replace( /^\s*\{|\}\s*$/g, "" );
				sa = source.split( /\,\s*/ig );
			}

			for( var i:int = 0; i < sa.length; i++ )
			{
				separator = ( sa[ i ] as String ).search( ":" );
				key = trim(( sa[ i ] as String ).substr( 0, separator ));
				value = trim(( sa[ i ] as String ).substr( separator + 1 ));

				// 值类型
				if( value.toLowerCase() == "true" || value.toLowerCase() == "false" )
				{
					obj[ key ] = Boolean( value );
				}
				else if( value.toLowerCase() == "nan" )
				{
					obj[ key ] = NaN;
				}
				else if( value.toLowerCase() == "null" )
				{
					obj[ key ] = null;
				}
				else if( value.search( /^\-?\d+(\.\d+)?(e(\+|\-)\d+)?$/ig ) != -1 )
				{
					// 数值
					obj[ key ] = Number( value );
				}
				else if( value.search( /^\s*\{/ig ) != -1 )
				{
					// 若找到对象起始符，则尝试从当前数组的最后一个元素搜索，寻找具有结束符的元素
					var search:int = searchObjectEnd( sa, i );

					if( search > i )
					{
						sa[ i ] = value.replace( "{", "" );
						sa[ search ] = String( sa[ search ]).replace( "}", "" );

						var ta:Array = sa.splice( i, search - i + 1 );
						obj[ key ] = decodeObject( null, ta );

						// 回退一步，因为去除当前新对象的元素后，已指向到下一个元素
						i--;
					}
					else
					{
						obj[ key ] = value.replace( /^"|"$/g, "" );
					}
				}
				else
				{
					// 字符串（不能识别的模式一律按字符串处理）
					obj[ key ] = value.replace( /^"|"$/g, "" );
				}
			}

			return obj;
		}

		protected static function searchObjectEnd( source:Array, start:int ):int
		{
			var field:Array;
			var key:String;
			var value:String;

			for( var j:int = source.length - 1; j > start; j-- )
			{
				field = ( source[ j ] as String ).split( /\s*\:\s*/i );
				key = trim( field[ 0 ]);
				value = trim( field[ 1 ]);

				if( value.search( /\}\s*$/ ) != -1 )
				{
					return j;
				}
			}

			return -1;
		}
	}
}
